#ifndef TERMINALDEVICE_H
#define TERMINALDEVICE_H


#ifdef DEBUG
#include "sceneelement.h"
#include "output_device.h"
#include "output_device_visitor.h"
#include <vector>

class TerminalDevice : public OutputDevice
{
public:
  TerminalDevice(Scene& s, std::ostream& strm) : out(strm), active_buff(&elements), scene(s) {}
  
  virtual void init() { out << "Terminal Device: initialized" << std::endl; }
  virtual void resize(unsigned int w, unsigned int h) 
  {
    out << " Terminal Device: resized " << w << ", " << h << std::endl;
  }
  virtual void redraw()
  {
    out << " Terminal Device: drawing " << std::endl;
    for(std::vector<SceneElement>::const_iterator i = elements.begin(), ie = elements.end(); i != ie; ++i) out << *i ;
    for(std::vector<SceneElement>::const_iterator i = selection.begin(), ie = selection.end(); i != ie; ++i) out << *i ;
  }
  virtual void clear() { elements.clear(); selection.clear(); }
  virtual void setScene(Scene& s ) { scene = s; }
  virtual void updateAll() 
  { 
    out << " Terminal Device: updating all" << std::endl;
    elements.clear();
    selection.clear();
    active_buff = &elements;
    OutputDeviceVisitor visitor(*this);
    for (Scene::element_const_iterator i = scene.elementsBegin(), ie = scene.elementsEnd(); i != ie; ++i)
    {
      out << 111 << std::endl;
      (*i)->visit(visitor);
    }
    active_buff = &selection;
    for (Scene::element_const_iterator i = scene.selectionBegin(), ie = scene.selectionEnd(); i != ie; ++i)
    {
      out << 222 << std::endl;
      (*i)->visit(visitor);
    }
    out << elements.size() << " elements and " << selection.size() << " selection elements" << std::endl;
  }
  virtual void updateSelection()
  { 
    out << " Terminal Device: updating selection only" << std::endl;
    selection.clear();
    active_buff = &selection;
    OutputDeviceVisitor visitor(*this);
    for (Scene::element_const_iterator i = scene.selectionBegin(), ie = scene.selectionEnd(); i != ie; ++i) (*i)->visit(visitor);
    out << elements.size() << " elements and " << selection.size() << " selection elements" << std::endl;
  }
  virtual void updateCamera()
  {
    out << " Terminal Device: updating camera only" << std::endl;
  }
  
  virtual void drawSphere(const Sphere& o) {active_buff->push_back(o);}
  virtual void drawEllipsoid(const Ellipsoid& o) {active_buff->push_back(o);}
  virtual void drawCylinder(const Cylinder& o) {active_buff->push_back(o);}
  virtual void drawCone(const Cone& o){active_buff->push_back(o);}
  virtual void drawParalelepiped(const Paralelepiped& o) {active_buff->push_back(o);}
  virtual void drawSurface(const Surface& o) {active_buff->push_back(o);}
  virtual void drawPoint(const Point& o) {active_buff->push_back(o);}
  virtual void drawLine(const Line& o) {active_buff->push_back(o);}
  virtual void drawText(const Text& o) {active_buff->push_back(o);}
  
private:
  std::ostream& out;
  
  std::vector<SceneElement> elements;
  std::vector<SceneElement> selection;
  std::vector<SceneElement>* active_buff;
  Scene& scene;
};

#endif // DEBUG
#endif // TERMINALDEVICE_H
